/* =============================================================================
 * PROJET           	: Matrices creuses
 * NOM DU FICHIER   	: Chargement.c
 * OBJET            	: Paquetage de programmes permettant l'acces au fichier de
 *							: definition des clauses et des variables
 * -----------------------------------------------------------------------------
 * DATE DE CREATION 	: 07/04/2009
 * AUTEUR           	: Ivan VALIMAHAMED, Sha LIU, Yves BOGE
 * -----------------------------------------------------------------------------
 * MODIFICATIONS (   n) date - auteur - description )
 * ============================================================================= */
 
#include "Chargement.h"

#define TAILLE_MAX 1000


/* 
 *	NOM 				: Affiche_contenu_fichier
 *	ENTREES 			: pointeur sur fichier i_F
 *	SORTIES			: void
 *	BUT				: Afficher l'ensemble du fichier texte sur la sortie standard
 */
 
void Affiche_contenu_fichier (FILE* i_F)
{
	char Chaine[TAILLE_MAX] = "";
	while (fgets(Chaine, TAILLE_MAX, i_F) != NULL)
	{
		printf("%s", Chaine);
	}
}


/* 
 *	NOM 				: Get_nb_var
 *	ENTREES 			: pointeur sur fichier i_F, pointeur positionne au debut du fichier
 *	SORTIES			: entier: nombre de variables, pointeur positionne avant le nombre de clauses
 *	BUT				: recuperer le nombre de variables contenu sur la premiere ligne du fichier
 */
 
int Get_nb_var (FILE* i_F)
{
	int Nb_var = 0;
	char Chaine[TAILLE_MAX] = "";
	
	if ( fgets(Chaine, TAILLE_MAX, i_F)	!= NULL )
	{
		Nb_var = atoi(Chaine);
	}
	
	return Nb_var;
}


/* 
 *	NOM 				: Get_nb_clauses
 *	ENTREES 			: pointeur sur fichier i_F, pointeur positionne avant le nombre de clauses
 *	SORTIES			: entier: nombre de variables, pointeur positionne apres le nombre de clauses
 *	BUT				: recuperer le nombre de clauses contenu sur la deuxieme ligne du fichier
 */
 
int Get_nb_clauses (FILE* i_F)
{
	int Nb_clauses = 0;
	char Chaine[TAILLE_MAX] = "";			/* recoit le contenu d'une ligne complete */
	
	if ( fgets(Chaine, TAILLE_MAX, i_F) != NULL )
	{
		Nb_clauses = atoi(Chaine);
	}
	
	return Nb_clauses;
}


/* 
 *	NOM 				: Affiche_litteraux
 *	ENTREES 			: pointeur sur fichier i_F, pointeur positionne apres le nombre de clauses
 *	SORTIES			: void, pointeur positionne a la fin du fichier
 *	BUT				: Afficher les litteraux par clauses (structure de controle de decoupage et traitement
 *						:	des clauses)
 */
 
void Affiche_litteraux (FILE* i_F)
{
	char C; 									/* caractere courant dans le fichier */
	char Chaine[TAILLE_MAX] = "";		/* chaine de caractere utilise pour le stockage du litteral */
	int i = 0;								/* indice dans le tableau "Chaine" */
	
					
	/* parcours du fichier, caractere par caractere */
	C = fgetc(i_F); 					
	while ( C != EOF )
	{
		/* Traitement selon le caractere */
		if ( C == ',' )
		{
			/* Si C==',' alors on reste sur la meme clause */
			Chaine[i] = '\0';
			printf("%s ",Chaine);
			i = 0;
		}
		else
		{
			if ( C == '\n' )
			{
				/* Si C=='\n' alors on change de clause */
				Chaine[i] = '\0';
				printf("%s\n",Chaine);
				i = 0;
			}
			else
			{
				/* sinon le litteral n'est pas completement parcouru, on continue */
				Chaine[i] = C;
				i++;
			}
		} 
		C = fgetc(i_F);
	}
	
}


/* 
 *	NOM 				: Get_litteraux
 *	ENTREES 			: pointeur sur fichier i_F, pointeur positionne apres le nombre de clauses
 *						: matrice de type t_Matrice de taille definie
 *	SORTIES			: matrice remplie avec les litteraux chaines
 *	BUT				: charger les litteraux dans la matrice
 */
 
void Get_litteraux (FILE* i_F , t_Matrice* io_Mat)
{
	char C; 									/* caractere courant dans le fichier */
	char Chaine[TAILLE_MAX] = "";		/* chaine de caractere utilise pour le stockage du litteral */
	int i = 0;								/* indice dans le tableau "Chaine" */
	t_Elem* E;								/* pointeur sur l'element en cours de traitement */
	int Num_clause = 1;					/* Numero de la clause courante */
	
	/* parcours du fichier, caractere par caractere */
	C = fgetc(i_F); 					
	while ( C != EOF )
	{
		E = malloc(sizeof(t_Elem));
		
		E->X.Signe = (C == '+' );	/* VRAI si +, FAUX sinon */
		
		/* Une fois le signe recupere, on capture le numero de la variable */
		i = 0;
		C = fgetc(i_F);
		while ( (C != ',') && (C != '\n') && (C != EOF) )
		{
			Chaine[i] = C;
			C = fgetc(i_F);
			i++;
		}
		Chaine[i] = '\0';
		
		/* stockage dans la structure du numero de la variable */
		E->X.Num_var = atoi(Chaine); 
		E->X.Num_clause = Num_clause;
		E->X.Val = 2; 			/* Valeur neutre a l'initialisation */ 
		io_Mat->Clause[Num_clause-1].Nb_neutres++; /* On incremente le nombre de litteraux 
																  * neutres de la clause
																  */ 
		E->Var_suiv = NULL;
		E->Clause_suiv = NULL;
		
		Ajout_element(E, io_Mat);
		if ( C == '\n' ) 
			Num_clause++;
			
		
		if ( C != EOF ) C = fgetc(i_F);
	}
	
}


/* 
 *	NOM 				: Get_matrice
 *	ENTREES 			: pointeur sur fichier i_F, pointeur positionne au debut du fichier
 *	SORTIES			: t_Matrice : une matrice contenant toutes les informations du probleme
 *	BUT				: Construire une matrice de type t_Matrice contenant tous les litteraux
 *						: contenus dans le fichier i_F
 */
 
t_Matrice Get_matrice (FILE* i_F)
{
	int Nb_var;
	int Nb_clauses;
	t_Matrice Mat; /* Declaration d'une matrice vide (on ne connait pas sa taille) */
	int i;
	
	Nb_var = Get_nb_var (i_F);
	Nb_clauses = Get_nb_clauses (i_F);
	
	/* 
	 * Allocation dynamique de la memoire pour creer la matrice: 
	 * on effectue une allocation separee pour le tableau des variables
	 * et le tableau des clauses.
	 */
	Mat.Var = malloc (Nb_var * ( sizeof(t_Elem*) + sizeof(int)) );
	Mat.Clause = malloc (Nb_clauses * sizeof(t_Elem*));
	
	Mat.Dernier_elem = NULL;
	Mat.Nb_var = Nb_var;
	Mat.Nb_clauses = Nb_clauses;
	
	for ( i = 0; i < Nb_var; i++) 
	{
		Mat.Var[i].Premier = NULL;
		Mat.Var[i].Valeur = 2; /* A l'initialisation toutes les variables sont a "neutre" */
	}
	for ( i = 0; i < Nb_clauses; i++) 
	{
		Mat.Clause[i].Etat = 2; /* Puisque toutes les variables sont neutres alors la clause est inchangee*/
		Mat.Clause[i].Nb_neutres = 0;
		Mat.Clause[i].Nb_satisfaits = 0;
		Mat.Clause[i].Nb_falsifies = 0;
		Mat.Clause[i].Premier = NULL;
	}
	
	Get_litteraux (i_F, &Mat);
	
	return Mat;
}

